package com.smartstate.admin.biz.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.smartstate.admin.biz.entity.bo.Role;
import com.smartstate.admin.biz.entity.bo.RolePermission;
import com.smartstate.admin.biz.entity.bo.User;
import com.smartstate.admin.biz.entity.bo.UserRole;
import com.smartstate.admin.biz.entity.dto.RoleDto;
import com.smartstate.admin.biz.entity.dto.RoleSearchDto;
import com.smartstate.admin.biz.entity.vo.RoleVo;
import com.smartstate.admin.biz.mapper.RoleMapper;
import com.smartstate.admin.biz.mapper.RolePermissionMapper;
import com.smartstate.admin.biz.mapper.UserRoleMapper;
import com.smartstate.admin.biz.model.LoginUser;
import com.smartstate.admin.biz.service.RoleService;
import com.smartstate.admin.biz.util.UserUtils;
import com.smartstate.common.base.constants.BizConstants;
import com.smartstate.common.base.exception.CommonException;
import com.smartstate.common.base.httpResult.ResultCode;
import org.apache.commons.lang3.StringUtils;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service("roleService")
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {

    @Resource
    private UserRoleMapper userRoleMapper;

    @Resource
    private RolePermissionMapper rolePermissionMapper;

    @Override
    public Role getRoleByUserId(String userId) {
        return baseMapper.getRoleByUserId(userId);
    }

    @Override
    public IPage<RoleVo> queryRoleList(RoleSearchDto roleSearchDto) {
        LoginUser loginUser = UserUtils.getLoginUser();
        roleSearchDto.setEnterpriseId(loginUser.getEnterpriseId());
        Page<RoleVo> page = roleSearchDto.initPage();
        return page.setRecords(baseMapper.selectRoleList(page, roleSearchDto));
    }

    @Override
    public RoleVo queryRoleById(String id) {
        return new RoleVo().buildVo(baseMapper.selectById(id));
    }

    @Transactional(rollbackFor = CommonException.class)
    @Override
    public Integer saveOrUpdateRole(RoleDto roleDto) {
        roleDto.setLoginUserId(UserUtils.getLoginUser().getId());
        Role role = new Role();
        role.buildBo(roleDto);

        Integer num = 0;
        if (StringUtils.isBlank(roleDto.getId())) {
            if (StringUtils.isNotBlank(role.getRoleCode())){
                List<Role> roles = baseMapper.selectList(new QueryWrapper<Role>().eq("ROLE_CODE", role.getRoleCode()).eq("STATUS",BizConstants.YES));
                if (roles.size() > 0) {
                    throw new CommonException("角色编码不能重复，请重新输入", ResultCode.RESOURCE_EXISTS.getCode());
                }
            }
            if (StringUtils.isNotBlank(role.getRoleName())){
                List<Role> roles = baseMapper.selectList(new QueryWrapper<Role>().eq("ROLE_NAME", role.getRoleName()).eq("STATUS",BizConstants.YES));
                if (roles.size() > 0) {
                    throw new CommonException("角色名称不能重复，请重新输入", ResultCode.RESOURCE_EXISTS.getCode());
                }
            }
            role.setCreateUser(roleDto.getLoginUserId());
            role.setEnterpriseId(UserUtils.getLoginUser().getEnterpriseId());
            role.setStatus(BizConstants.YES);
            num = baseMapper.insert(role);
        } else {
            if (StringUtils.isNotBlank(role.getRoleCode())){
                List<Role> roles = baseMapper.selectList(new QueryWrapper<Role>().eq("ROLE_CODE", role.getRoleCode()).eq("STATUS",BizConstants.YES).ne("ID",role.getId()));
                if (roles.size() > 0) {
                    throw new CommonException("角色编码不能重复，请重新输入", ResultCode.RESOURCE_EXISTS.getCode());
                }
            }
            if (StringUtils.isNotBlank(role.getRoleName())){
                List<Role> roles = baseMapper.selectList(new QueryWrapper<Role>().eq("ROLE_NAME", role.getRoleName()).eq("STATUS",BizConstants.YES).ne("ID",role.getId()));
                if (roles.size() > 0) {
                    throw new CommonException("角色名称不能重复，请重新输入", ResultCode.RESOURCE_EXISTS.getCode());
                }
            }
            role.setUpdateUser(roleDto.getLoginUserId());
            num = baseMapper.updateById(role);
        }
        return num;
    }

    @Transactional(rollbackFor = CommonException.class)
    @Override
    public Map<String, Object> deleteRole(String id) {
        Map<String, Object> map = new HashMap<>(16);
        List<UserRole> userRoles = userRoleMapper.selectList(new QueryWrapper<UserRole>().eq("ROLE_ID", id).ne("USER_ID", UserUtils.getLoginUser().getId()));
        if (userRoles.size() > 0) {
            map.put("msg", "该角色已有其他用户关联");
            map.put("flag", false);
            return map;
        }
        Role role = new Role();
        role.setId(id);
        role.setStatus(BizConstants.NO);
        role.setUpdateTime(LocalDateTime.now());
        role.setUpdateUser(UserUtils.getLoginUser().getId());
        int i = baseMapper.updateById(role);
        rolePermissionMapper.delete(new QueryWrapper<RolePermission>().eq("ROLE_ID", id));
        userRoleMapper.delete(new QueryWrapper<UserRole>().eq("ROLE_ID", id));
        if (i > 0) {
            map.put("msg", "删除成功");
            map.put("flag", true);
        } else {
            map.put("msg", "删除失败");
            map.put("flag", false);
        }
        return map;
    }

    @Transactional(rollbackFor = CommonException.class)
    @Override
    public Map<String, Object> deleteBatchRole(List<String> ids) {
        Map<String, Object> map = new HashMap<>(16);
        ids.parallelStream().forEach(
                x -> {
                    List<UserRole> userRoleList = userRoleMapper.selectList(new QueryWrapper<UserRole>().eq("ROLE_ID", x).ne("USER_ID", UserUtils.getLoginUser().getId()));
                    if (userRoleList.size() > 0) {
                        map.put("msg", "选取的其中角色已有其他用户关联");
                        map.put("flag", false);
                    }
                }
        );
        if (map.size() > 0) {
            return map;
        }
        int i = baseMapper.updateBatchByIds(ids);
        rolePermissionMapper.deleteBatchByRoleIds(ids);
        userRoleMapper.deleteBatchByRoleIds(ids);
        if (i > 0) {
            map.put("msg", "批量删除成功");
            map.put("flag", true);
        } else {
            map.put("msg", "批量删除失败");
            map.put("flag", false);
        }
        return map;
    }

    @Override
    public List<RoleVo> queryRole(String userId) {
        if (StringUtils.isBlank(userId)) {
            userId = UserUtils.getLoginUser().getId();
        }
        Role role = baseMapper.getRoleByUserId(userId);
        return baseMapper.selectRole(role.getRoleCode());
    }

    @Override
    public Map<String, Object> checkRoleCode(String roleId, String roleCode) {
        Map<String, Object> map = new HashMap<>(16);
        map.put("flag", true);
        List<Role> roles = new ArrayList<>();
        if (StringUtils.isNotBlank(roleId)){
            roles = baseMapper.selectList(new QueryWrapper<Role>().eq("ROLE_CODE", roleCode).eq("STATUS",BizConstants.YES).ne("ID",roleId));
        }else {
            roles = baseMapper.selectList(new QueryWrapper<Role>().eq("ROLE_CODE", roleCode).eq("STATUS",BizConstants.YES));
        }
        if (roles.size() > 0) {
            throw new CommonException("角色编号不能重复，请重新输入", ResultCode.RESOURCE_EXISTS.getCode());
        }
        return map;
    }

    @Override
    public Map<String, Object> checkRoleName(String roleId, String roleName) {
        Map<String, Object> map = new HashMap<>(16);
        map.put("flag", true);
        List<Role> roles = new ArrayList<>();
        if (StringUtils.isNotBlank(roleId)){
            roles = baseMapper.selectList(new QueryWrapper<Role>().eq("ROLE_NAME", roleName).eq("STATUS",BizConstants.YES));
        }else {
            roles = baseMapper.selectList(new QueryWrapper<Role>().eq("ROLE_NAME", roleName));
        }
        if (roles.size() > 0) {
            throw new CommonException("角色名称不能重复，请重新输入", ResultCode.RESOURCE_EXISTS.getCode());
        }
        return map;
    }

    @Override
    public String getRoleIdByRoleName(String roleName) {
        return baseMapper.selectOne(new QueryWrapper<Role>().eq("ROLE_NAME",roleName)).getId();
    }
}
